//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension ACM {
    // MARK: Enums

    public enum CertificateExport: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        public var description: String { return self.rawValue }
    }

    public enum CertificateManagedBy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cloudfront = "CLOUDFRONT"
        public var description: String { return self.rawValue }
    }

    public enum CertificateStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case expired = "EXPIRED"
        case failed = "FAILED"
        case inactive = "INACTIVE"
        case issued = "ISSUED"
        case pendingValidation = "PENDING_VALIDATION"
        case revoked = "REVOKED"
        case validationTimedOut = "VALIDATION_TIMED_OUT"
        public var description: String { return self.rawValue }
    }

    public enum CertificateTransparencyLoggingPreference: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        public var description: String { return self.rawValue }
    }

    public enum CertificateType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case `private` = "PRIVATE"
        case amazonIssued = "AMAZON_ISSUED"
        case imported = "IMPORTED"
        public var description: String { return self.rawValue }
    }

    public enum DomainStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case failed = "FAILED"
        case pendingValidation = "PENDING_VALIDATION"
        case success = "SUCCESS"
        public var description: String { return self.rawValue }
    }

    public enum ExtendedKeyUsageName: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case any = "ANY"
        case codeSigning = "CODE_SIGNING"
        case custom = "CUSTOM"
        case emailProtection = "EMAIL_PROTECTION"
        case ipsecEndSystem = "IPSEC_END_SYSTEM"
        case ipsecTunnel = "IPSEC_TUNNEL"
        case ipsecUser = "IPSEC_USER"
        case none = "NONE"
        case ocspSigning = "OCSP_SIGNING"
        case timeStamping = "TIME_STAMPING"
        case tlsWebClientAuthentication = "TLS_WEB_CLIENT_AUTHENTICATION"
        case tlsWebServerAuthentication = "TLS_WEB_SERVER_AUTHENTICATION"
        public var description: String { return self.rawValue }
    }

    public enum FailureReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case additionalVerificationRequired = "ADDITIONAL_VERIFICATION_REQUIRED"
        case caaError = "CAA_ERROR"
        case domainNotAllowed = "DOMAIN_NOT_ALLOWED"
        case domainValidationDenied = "DOMAIN_VALIDATION_DENIED"
        case invalidPublicDomain = "INVALID_PUBLIC_DOMAIN"
        case noAvailableContacts = "NO_AVAILABLE_CONTACTS"
        case other = "OTHER"
        case pcaAccessDenied = "PCA_ACCESS_DENIED"
        case pcaInvalidArgs = "PCA_INVALID_ARGS"
        case pcaInvalidArn = "PCA_INVALID_ARN"
        case pcaInvalidDuration = "PCA_INVALID_DURATION"
        case pcaInvalidState = "PCA_INVALID_STATE"
        case pcaLimitExceeded = "PCA_LIMIT_EXCEEDED"
        case pcaNameConstraintsValidation = "PCA_NAME_CONSTRAINTS_VALIDATION"
        case pcaRequestFailed = "PCA_REQUEST_FAILED"
        case pcaResourceNotFound = "PCA_RESOURCE_NOT_FOUND"
        case slrNotFound = "SLR_NOT_FOUND"
        public var description: String { return self.rawValue }
    }

    public enum KeyAlgorithm: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ecPrime256V1 = "EC-prime256v1"
        case ecSecp384R1 = "EC-secp384r1"
        case ecSecp521R1 = "EC-secp521r1"
        case rsa1024 = "RSA-1024"
        case rsa2048 = "RSA-2048"
        case rsa3072 = "RSA-3072"
        case rsa4096 = "RSA-4096"
        public var description: String { return self.rawValue }
    }

    public enum KeyUsageName: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case any = "ANY"
        case certificateSigning = "CERTIFICATE_SIGNING"
        case crlSigning = "CRL_SIGNING"
        case custom = "CUSTOM"
        case dataEncipherment = "DATA_ENCIPHERMENT"
        case decipherOnly = "DECIPHER_ONLY"
        case digitalSignature = "DIGITAL_SIGNATURE"
        case enchiperOnly = "ENCIPHER_ONLY"
        case keyAgreement = "KEY_AGREEMENT"
        case keyEncipherment = "KEY_ENCIPHERMENT"
        case nonRepudation = "NON_REPUDIATION"
        public var description: String { return self.rawValue }
    }

    public enum RecordType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cname = "CNAME"
        public var description: String { return self.rawValue }
    }

    public enum RenewalEligibility: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case eligible = "ELIGIBLE"
        case ineligible = "INELIGIBLE"
        public var description: String { return self.rawValue }
    }

    public enum RenewalStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case failed = "FAILED"
        case pendingAutoRenewal = "PENDING_AUTO_RENEWAL"
        case pendingValidation = "PENDING_VALIDATION"
        case success = "SUCCESS"
        public var description: String { return self.rawValue }
    }

    public enum RevocationReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case aACompromise = "A_A_COMPROMISE"
        case affiliationChanged = "AFFILIATION_CHANGED"
        case caCompromise = "CA_COMPROMISE"
        case certificateHold = "CERTIFICATE_HOLD"
        case cessationOfOperation = "CESSATION_OF_OPERATION"
        case keyCompromise = "KEY_COMPROMISE"
        case privilegeWithdrawn = "PRIVILEGE_WITHDRAWN"
        case removeFromCrl = "REMOVE_FROM_CRL"
        case superceded = "SUPERCEDED"
        case superseded = "SUPERSEDED"
        case unspecified = "UNSPECIFIED"
        public var description: String { return self.rawValue }
    }

    public enum SortBy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case createdAt = "CREATED_AT"
        public var description: String { return self.rawValue }
    }

    public enum SortOrder: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ascending = "ASCENDING"
        case descending = "DESCENDING"
        public var description: String { return self.rawValue }
    }

    public enum ValidationMethod: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dns = "DNS"
        case email = "EMAIL"
        case http = "HTTP"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AddTagsToCertificateRequest: AWSEncodableShape {
        /// String that contains the ARN of the ACM certificate to which the tag is to be applied. This must be of the form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String
        /// The key-value pair that defines the tag. The tag value is optional.
        public let tags: [Tag]

        @inlinable
        public init(certificateArn: String, tags: [Tag]) {
            self.certificateArn = certificateArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case tags = "Tags"
        }
    }

    public struct CertificateDetail: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the certificate. For more information about ARNs, see Amazon Resource Names (ARNs) in the Amazon Web Services General Reference.
        public let certificateArn: String?
        /// The Amazon Resource Name (ARN) of the private certificate authority (CA) that issued the certificate. This has the following format:   arn:aws:acm-pca:region:account:certificate-authority/12345678-1234-1234-1234-123456789012
        public let certificateAuthorityArn: String?
        /// The time at which the certificate was requested.
        public let createdAt: Date?
        /// The fully qualified domain name for the certificate, such as www.example.com or example.com.
        public let domainName: String?
        /// Contains information about the initial validation of each domain name that occurs as a result of the RequestCertificate request. This field exists only when the certificate type is AMAZON_ISSUED.
        public let domainValidationOptions: [DomainValidation]?
        /// Contains a list of Extended Key Usage X.509 v3 extension objects. Each object specifies a purpose for which the certificate public key can be used and consists of a name and an object identifier (OID).
        public let extendedKeyUsages: [ExtendedKeyUsage]?
        /// The reason the certificate request failed. This value exists only when the certificate status is FAILED. For more information, see Certificate Request Failed in the Certificate Manager User Guide.
        public let failureReason: FailureReason?
        /// The date and time when the certificate was imported. This value exists only when the certificate type is IMPORTED.
        public let importedAt: Date?
        /// A list of ARNs for the Amazon Web Services resources that are using the certificate. A certificate can be used by multiple Amazon Web Services resources.
        public let inUseBy: [String]?
        /// The time at which the certificate was issued. This value exists only when the certificate type is AMAZON_ISSUED.
        public let issuedAt: Date?
        /// The name of the certificate authority that issued and signed the certificate.
        public let issuer: String?
        /// The algorithm that was used to generate the public-private key pair.
        public let keyAlgorithm: KeyAlgorithm?
        /// A list of Key Usage X.509 v3 extension objects. Each object is a string value that identifies the purpose of the public key contained in the certificate. Possible extension values include DIGITAL_SIGNATURE, KEY_ENCHIPHERMENT, NON_REPUDIATION, and more.
        public let keyUsages: [KeyUsage]?
        /// Identifies the Amazon Web Services service that manages the certificate issued by ACM.
        public let managedBy: CertificateManagedBy?
        /// The time after which the certificate is not valid.
        public let notAfter: Date?
        /// The time before which the certificate is not valid.
        public let notBefore: Date?
        /// Value that specifies whether to add the certificate to a transparency log. Certificate transparency makes it possible to detect SSL certificates that have been mistakenly or maliciously issued. A browser might respond to certificate that has not been logged by showing an error message. The logs are cryptographically secure.
        public let options: CertificateOptions?
        /// Specifies whether the certificate is eligible for renewal. At this time, only exported private certificates can be renewed with the RenewCertificate command.
        public let renewalEligibility: RenewalEligibility?
        /// Contains information about the status of ACM's managed renewal for the certificate. This field exists only when the certificate type is AMAZON_ISSUED.
        public let renewalSummary: RenewalSummary?
        /// The reason the certificate was revoked. This value exists only when the certificate status is REVOKED.
        public let revocationReason: RevocationReason?
        /// The time at which the certificate was revoked. This value exists only when the certificate status is REVOKED.
        public let revokedAt: Date?
        /// The serial number of the certificate.
        public let serial: String?
        /// The algorithm that was used to sign the certificate.
        public let signatureAlgorithm: String?
        /// The status of the certificate. A certificate enters status PENDING_VALIDATION upon being requested, unless it fails for any of the reasons given in the troubleshooting topic Certificate request fails. ACM makes repeated attempts to validate a certificate for 72 hours and then times out. If a certificate shows status FAILED or VALIDATION_TIMED_OUT, delete the request, correct the issue with DNS validation or Email validation, and try again. If validation succeeds, the certificate enters status ISSUED.
        public let status: CertificateStatus?
        /// The name of the entity that is associated with the public key contained in the certificate.
        public let subject: String?
        /// One or more domain names (subject alternative names) included in the certificate. This list contains the domain names that are bound to the public key that is contained in the certificate. The subject alternative names include the canonical domain name (CN) of the certificate and additional domain names that can be used to connect to the website.
        public let subjectAlternativeNames: [String]?
        /// The source of the certificate. For certificates provided by ACM, this value is AMAZON_ISSUED. For certificates that you imported with ImportCertificate, this value is IMPORTED. ACM does not provide managed renewal for imported certificates. For more information about the differences between certificates that you import and those that ACM provides, see Importing Certificates in the Certificate Manager User Guide.
        public let type: CertificateType?

        @inlinable
        public init(certificateArn: String? = nil, certificateAuthorityArn: String? = nil, createdAt: Date? = nil, domainName: String? = nil, domainValidationOptions: [DomainValidation]? = nil, extendedKeyUsages: [ExtendedKeyUsage]? = nil, failureReason: FailureReason? = nil, importedAt: Date? = nil, inUseBy: [String]? = nil, issuedAt: Date? = nil, issuer: String? = nil, keyAlgorithm: KeyAlgorithm? = nil, keyUsages: [KeyUsage]? = nil, managedBy: CertificateManagedBy? = nil, notAfter: Date? = nil, notBefore: Date? = nil, options: CertificateOptions? = nil, renewalEligibility: RenewalEligibility? = nil, renewalSummary: RenewalSummary? = nil, revocationReason: RevocationReason? = nil, revokedAt: Date? = nil, serial: String? = nil, signatureAlgorithm: String? = nil, status: CertificateStatus? = nil, subject: String? = nil, subjectAlternativeNames: [String]? = nil, type: CertificateType? = nil) {
            self.certificateArn = certificateArn
            self.certificateAuthorityArn = certificateAuthorityArn
            self.createdAt = createdAt
            self.domainName = domainName
            self.domainValidationOptions = domainValidationOptions
            self.extendedKeyUsages = extendedKeyUsages
            self.failureReason = failureReason
            self.importedAt = importedAt
            self.inUseBy = inUseBy
            self.issuedAt = issuedAt
            self.issuer = issuer
            self.keyAlgorithm = keyAlgorithm
            self.keyUsages = keyUsages
            self.managedBy = managedBy
            self.notAfter = notAfter
            self.notBefore = notBefore
            self.options = options
            self.renewalEligibility = renewalEligibility
            self.renewalSummary = renewalSummary
            self.revocationReason = revocationReason
            self.revokedAt = revokedAt
            self.serial = serial
            self.signatureAlgorithm = signatureAlgorithm
            self.status = status
            self.subject = subject
            self.subjectAlternativeNames = subjectAlternativeNames
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case certificateAuthorityArn = "CertificateAuthorityArn"
            case createdAt = "CreatedAt"
            case domainName = "DomainName"
            case domainValidationOptions = "DomainValidationOptions"
            case extendedKeyUsages = "ExtendedKeyUsages"
            case failureReason = "FailureReason"
            case importedAt = "ImportedAt"
            case inUseBy = "InUseBy"
            case issuedAt = "IssuedAt"
            case issuer = "Issuer"
            case keyAlgorithm = "KeyAlgorithm"
            case keyUsages = "KeyUsages"
            case managedBy = "ManagedBy"
            case notAfter = "NotAfter"
            case notBefore = "NotBefore"
            case options = "Options"
            case renewalEligibility = "RenewalEligibility"
            case renewalSummary = "RenewalSummary"
            case revocationReason = "RevocationReason"
            case revokedAt = "RevokedAt"
            case serial = "Serial"
            case signatureAlgorithm = "SignatureAlgorithm"
            case status = "Status"
            case subject = "Subject"
            case subjectAlternativeNames = "SubjectAlternativeNames"
            case type = "Type"
        }
    }

    public struct CertificateOptions: AWSEncodableShape & AWSDecodableShape {
        /// You can opt out of certificate transparency logging by specifying the DISABLED option. Opt in by specifying ENABLED.
        public let certificateTransparencyLoggingPreference: CertificateTransparencyLoggingPreference?
        /// You can opt in to allow the export of your certificates by specifying ENABLED.
        public let export: CertificateExport?

        @inlinable
        public init(certificateTransparencyLoggingPreference: CertificateTransparencyLoggingPreference? = nil, export: CertificateExport? = nil) {
            self.certificateTransparencyLoggingPreference = certificateTransparencyLoggingPreference
            self.export = export
        }

        private enum CodingKeys: String, CodingKey {
            case certificateTransparencyLoggingPreference = "CertificateTransparencyLoggingPreference"
            case export = "Export"
        }
    }

    public struct CertificateSummary: AWSDecodableShape {
        /// Amazon Resource Name (ARN) of the certificate. This is of the form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String?
        /// The time at which the certificate was requested.
        public let createdAt: Date?
        /// Fully qualified domain name (FQDN), such as www.example.com or example.com, for the certificate.
        public let domainName: String?
        /// Indicates whether the certificate has been exported. This value exists only when the certificate type is PRIVATE.
        public let exported: Bool?
        /// Indicates if export is enabled for the certificate.
        public let exportOption: CertificateExport?
        /// Contains a list of Extended Key Usage X.509 v3 extension objects. Each object specifies a purpose for which the certificate public key can be used and consists of a name and an object identifier (OID).
        public let extendedKeyUsages: [ExtendedKeyUsageName]?
        /// When called by ListCertificates, indicates whether the full list of subject alternative names has been included in the response. If false, the response includes all of the subject alternative names included in the certificate. If true, the response only includes the first 100 subject alternative names included in the certificate. To display the full list of subject alternative names, use DescribeCertificate.
        public let hasAdditionalSubjectAlternativeNames: Bool?
        /// The date and time when the certificate was imported. This value exists only when the certificate type is IMPORTED.
        public let importedAt: Date?
        /// Indicates whether the certificate is currently in use by any Amazon Web Services resources.
        public let inUse: Bool?
        /// The time at which the certificate was issued. This value exists only when the certificate type is AMAZON_ISSUED.
        public let issuedAt: Date?
        /// The algorithm that was used to generate the public-private key pair.
        public let keyAlgorithm: KeyAlgorithm?
        /// A list of Key Usage X.509 v3 extension objects. Each object is a string value that identifies the purpose of the public key contained in the certificate. Possible extension values include DIGITAL_SIGNATURE, KEY_ENCHIPHERMENT, NON_REPUDIATION, and more.
        public let keyUsages: [KeyUsageName]?
        /// Identifies the Amazon Web Services service that manages the certificate issued by ACM.
        public let managedBy: CertificateManagedBy?
        /// The time after which the certificate is not valid.
        public let notAfter: Date?
        /// The time before which the certificate is not valid.
        public let notBefore: Date?
        /// Specifies whether the certificate is eligible for renewal. At this time, only exported private certificates can be renewed with the RenewCertificate command.
        public let renewalEligibility: RenewalEligibility?
        /// The time at which the certificate was revoked. This value exists only when the certificate status is REVOKED.
        public let revokedAt: Date?
        /// The status of the certificate. A certificate enters status PENDING_VALIDATION upon being requested, unless it fails for any of the reasons given in the troubleshooting topic Certificate request fails. ACM makes repeated attempts to validate a certificate for 72 hours and then times out. If a certificate shows status FAILED or VALIDATION_TIMED_OUT, delete the request, correct the issue with DNS validation or Email validation, and try again. If validation succeeds, the certificate enters status ISSUED.
        public let status: CertificateStatus?
        /// One or more domain names (subject alternative names) included in the certificate. This list contains the domain names that are bound to the public key that is contained in the certificate. The subject alternative names include the canonical domain name (CN) of the certificate and additional domain names that can be used to connect to the website.  When called by ListCertificates, this parameter will only return the first 100 subject alternative names included in the certificate. To display the full list of subject alternative names, use DescribeCertificate.
        public let subjectAlternativeNameSummaries: [String]?
        /// The source of the certificate. For certificates provided by ACM, this value is AMAZON_ISSUED. For certificates that you imported with ImportCertificate, this value is IMPORTED. ACM does not provide managed renewal for imported certificates. For more information about the differences between certificates that you import and those that ACM provides, see Importing Certificates in the Certificate Manager User Guide.
        public let type: CertificateType?

        @inlinable
        public init(certificateArn: String? = nil, createdAt: Date? = nil, domainName: String? = nil, exported: Bool? = nil, exportOption: CertificateExport? = nil, extendedKeyUsages: [ExtendedKeyUsageName]? = nil, hasAdditionalSubjectAlternativeNames: Bool? = nil, importedAt: Date? = nil, inUse: Bool? = nil, issuedAt: Date? = nil, keyAlgorithm: KeyAlgorithm? = nil, keyUsages: [KeyUsageName]? = nil, managedBy: CertificateManagedBy? = nil, notAfter: Date? = nil, notBefore: Date? = nil, renewalEligibility: RenewalEligibility? = nil, revokedAt: Date? = nil, status: CertificateStatus? = nil, subjectAlternativeNameSummaries: [String]? = nil, type: CertificateType? = nil) {
            self.certificateArn = certificateArn
            self.createdAt = createdAt
            self.domainName = domainName
            self.exported = exported
            self.exportOption = exportOption
            self.extendedKeyUsages = extendedKeyUsages
            self.hasAdditionalSubjectAlternativeNames = hasAdditionalSubjectAlternativeNames
            self.importedAt = importedAt
            self.inUse = inUse
            self.issuedAt = issuedAt
            self.keyAlgorithm = keyAlgorithm
            self.keyUsages = keyUsages
            self.managedBy = managedBy
            self.notAfter = notAfter
            self.notBefore = notBefore
            self.renewalEligibility = renewalEligibility
            self.revokedAt = revokedAt
            self.status = status
            self.subjectAlternativeNameSummaries = subjectAlternativeNameSummaries
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case createdAt = "CreatedAt"
            case domainName = "DomainName"
            case exported = "Exported"
            case exportOption = "ExportOption"
            case extendedKeyUsages = "ExtendedKeyUsages"
            case hasAdditionalSubjectAlternativeNames = "HasAdditionalSubjectAlternativeNames"
            case importedAt = "ImportedAt"
            case inUse = "InUse"
            case issuedAt = "IssuedAt"
            case keyAlgorithm = "KeyAlgorithm"
            case keyUsages = "KeyUsages"
            case managedBy = "ManagedBy"
            case notAfter = "NotAfter"
            case notBefore = "NotBefore"
            case renewalEligibility = "RenewalEligibility"
            case revokedAt = "RevokedAt"
            case status = "Status"
            case subjectAlternativeNameSummaries = "SubjectAlternativeNameSummaries"
            case type = "Type"
        }
    }

    public struct DeleteCertificateRequest: AWSEncodableShape {
        /// String that contains the ARN of the ACM certificate to be deleted. This must be of the form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String

        @inlinable
        public init(certificateArn: String) {
            self.certificateArn = certificateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct DescribeCertificateRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the ACM certificate. The ARN must have the following form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String

        @inlinable
        public init(certificateArn: String) {
            self.certificateArn = certificateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct DescribeCertificateResponse: AWSDecodableShape {
        /// Metadata about an ACM certificate.
        public let certificate: CertificateDetail?

        @inlinable
        public init(certificate: CertificateDetail? = nil) {
            self.certificate = certificate
        }

        private enum CodingKeys: String, CodingKey {
            case certificate = "Certificate"
        }
    }

    public struct DomainValidation: AWSDecodableShape {
        /// A fully qualified domain name (FQDN) in the certificate. For example, www.example.com or example.com.
        public let domainName: String
        /// Contains information for HTTP-based domain validation of certificates requested through Amazon CloudFront and issued by ACM. This field exists only when the certificate type is AMAZON_ISSUED and the validation method is HTTP.
        public let httpRedirect: HttpRedirect?
        /// Contains the CNAME record that you add to your DNS database for domain validation. For more information, see Use DNS to Validate Domain Ownership.  The CNAME information that you need does not include the name of your domain. If you include your domain name in the DNS database CNAME record, validation fails. For example, if the name is _a79865eb4cd1a6ab990a45779b4e0b96.yourdomain.com, only _a79865eb4cd1a6ab990a45779b4e0b96 must be used.
        public let resourceRecord: ResourceRecord?
        /// The domain name that ACM used to send domain validation emails.
        public let validationDomain: String?
        /// A list of email addresses that ACM used to send domain validation emails.
        public let validationEmails: [String]?
        /// Specifies the domain validation method.
        public let validationMethod: ValidationMethod?
        /// The validation status of the domain name. This can be one of the following values:    PENDING_VALIDATION     SUCCESS    FAILED
        public let validationStatus: DomainStatus?

        @inlinable
        public init(domainName: String, httpRedirect: HttpRedirect? = nil, resourceRecord: ResourceRecord? = nil, validationDomain: String? = nil, validationEmails: [String]? = nil, validationMethod: ValidationMethod? = nil, validationStatus: DomainStatus? = nil) {
            self.domainName = domainName
            self.httpRedirect = httpRedirect
            self.resourceRecord = resourceRecord
            self.validationDomain = validationDomain
            self.validationEmails = validationEmails
            self.validationMethod = validationMethod
            self.validationStatus = validationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case domainName = "DomainName"
            case httpRedirect = "HttpRedirect"
            case resourceRecord = "ResourceRecord"
            case validationDomain = "ValidationDomain"
            case validationEmails = "ValidationEmails"
            case validationMethod = "ValidationMethod"
            case validationStatus = "ValidationStatus"
        }
    }

    public struct DomainValidationOption: AWSEncodableShape {
        /// A fully qualified domain name (FQDN) in the certificate request.
        public let domainName: String
        /// The domain name that you want ACM to use to send you validation emails. This domain name is the suffix of the email addresses that you want ACM to use. This must be the same as the DomainName value or a superdomain of the DomainName value. For example, if you request a certificate for testing.example.com, you can specify example.com for this value. In that case, ACM sends domain validation emails to the following five addresses:   admin@example.com   administrator@example.com   hostmaster@example.com   postmaster@example.com   webmaster@example.com
        public let validationDomain: String

        @inlinable
        public init(domainName: String, validationDomain: String) {
            self.domainName = domainName
            self.validationDomain = validationDomain
        }

        public func validate(name: String) throws {
            try self.validate(self.domainName, name: "domainName", parent: name, max: 253)
            try self.validate(self.domainName, name: "domainName", parent: name, min: 1)
            try self.validate(self.domainName, name: "domainName", parent: name, pattern: "^(\\*\\.)?(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
            try self.validate(self.validationDomain, name: "validationDomain", parent: name, max: 253)
            try self.validate(self.validationDomain, name: "validationDomain", parent: name, min: 1)
            try self.validate(self.validationDomain, name: "validationDomain", parent: name, pattern: "^(\\*\\.)?(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainName = "DomainName"
            case validationDomain = "ValidationDomain"
        }
    }

    public struct ExpiryEventsConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Specifies the number of days prior to certificate expiration when ACM starts generating EventBridge events. ACM sends one event per day per certificate until the certificate expires. By default, accounts receive events starting 45 days before certificate expiration.
        public let daysBeforeExpiry: Int?

        @inlinable
        public init(daysBeforeExpiry: Int? = nil) {
            self.daysBeforeExpiry = daysBeforeExpiry
        }

        public func validate(name: String) throws {
            try self.validate(self.daysBeforeExpiry, name: "daysBeforeExpiry", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case daysBeforeExpiry = "DaysBeforeExpiry"
        }
    }

    public struct ExportCertificateRequest: AWSEncodableShape {
        /// An Amazon Resource Name (ARN) of the issued certificate. This must be of the form:  arn:aws:acm:region:account:certificate/12345678-1234-1234-1234-123456789012
        public let certificateArn: String
        /// Passphrase to associate with the encrypted exported private key.   When creating your passphrase, you can use any ASCII character except #, $, or %.  If you want to later decrypt the private key, you must have the passphrase. You can use the following OpenSSL command to decrypt a private key. After entering the command, you are prompted for the passphrase.  openssl rsa -in encrypted_key.pem -out decrypted_key.pem
        public let passphrase: AWSBase64Data

        @inlinable
        public init(certificateArn: String, passphrase: AWSBase64Data) {
            self.certificateArn = certificateArn
            self.passphrase = passphrase
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
            try self.validate(self.passphrase, name: "passphrase", parent: name, max: 128)
            try self.validate(self.passphrase, name: "passphrase", parent: name, min: 4)
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case passphrase = "Passphrase"
        }
    }

    public struct ExportCertificateResponse: AWSDecodableShape {
        /// The base64 PEM-encoded certificate.
        public let certificate: String?
        /// The base64 PEM-encoded certificate chain. This does not include the certificate that you are exporting.
        public let certificateChain: String?
        /// The encrypted private key associated with the public key in the certificate. The key is output in PKCS #8 format and is base64 PEM-encoded.
        public let privateKey: String?

        @inlinable
        public init(certificate: String? = nil, certificateChain: String? = nil, privateKey: String? = nil) {
            self.certificate = certificate
            self.certificateChain = certificateChain
            self.privateKey = privateKey
        }

        private enum CodingKeys: String, CodingKey {
            case certificate = "Certificate"
            case certificateChain = "CertificateChain"
            case privateKey = "PrivateKey"
        }
    }

    public struct ExtendedKeyUsage: AWSDecodableShape {
        /// The name of an Extended Key Usage value.
        public let name: ExtendedKeyUsageName?
        /// An object identifier (OID) for the extension value. OIDs are strings of numbers separated by periods. The following OIDs are defined in RFC 3280 and RFC 5280.     1.3.6.1.5.5.7.3.1 (TLS_WEB_SERVER_AUTHENTICATION)     1.3.6.1.5.5.7.3.2 (TLS_WEB_CLIENT_AUTHENTICATION)     1.3.6.1.5.5.7.3.3 (CODE_SIGNING)     1.3.6.1.5.5.7.3.4 (EMAIL_PROTECTION)     1.3.6.1.5.5.7.3.8 (TIME_STAMPING)     1.3.6.1.5.5.7.3.9 (OCSP_SIGNING)     1.3.6.1.5.5.7.3.5 (IPSEC_END_SYSTEM)     1.3.6.1.5.5.7.3.6 (IPSEC_TUNNEL)     1.3.6.1.5.5.7.3.7 (IPSEC_USER)
        public let oid: String?

        @inlinable
        public init(name: ExtendedKeyUsageName? = nil, oid: String? = nil) {
            self.name = name
            self.oid = oid
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case oid = "OID"
        }
    }

    public struct Filters: AWSEncodableShape {
        /// Specify ENABLED or DISABLED to identify certificates that can be exported.
        public let exportOption: CertificateExport?
        /// Specify one or more ExtendedKeyUsage extension values.
        public let extendedKeyUsage: [ExtendedKeyUsageName]?
        /// Specify one or more algorithms that can be used to generate key pairs. Default filtering returns only RSA_1024 and RSA_2048 certificates that have at least one domain. To return other certificate types, provide the desired type signatures in a comma-separated list. For example, "keyTypes": ["RSA_2048","RSA_4096"] returns both RSA_2048 and RSA_4096 certificates.
        public let keyTypes: [KeyAlgorithm]?
        /// Specify one or more KeyUsage extension values.
        public let keyUsage: [KeyUsageName]?
        /// Identifies the Amazon Web Services service that manages the certificate issued by ACM.
        public let managedBy: CertificateManagedBy?

        @inlinable
        public init(exportOption: CertificateExport? = nil, extendedKeyUsage: [ExtendedKeyUsageName]? = nil, keyTypes: [KeyAlgorithm]? = nil, keyUsage: [KeyUsageName]? = nil, managedBy: CertificateManagedBy? = nil) {
            self.exportOption = exportOption
            self.extendedKeyUsage = extendedKeyUsage
            self.keyTypes = keyTypes
            self.keyUsage = keyUsage
            self.managedBy = managedBy
        }

        private enum CodingKeys: String, CodingKey {
            case exportOption = "exportOption"
            case extendedKeyUsage = "extendedKeyUsage"
            case keyTypes = "keyTypes"
            case keyUsage = "keyUsage"
            case managedBy = "managedBy"
        }
    }

    public struct GetAccountConfigurationResponse: AWSDecodableShape {
        /// Expiration events configuration options associated with the Amazon Web Services account.
        public let expiryEvents: ExpiryEventsConfiguration?

        @inlinable
        public init(expiryEvents: ExpiryEventsConfiguration? = nil) {
            self.expiryEvents = expiryEvents
        }

        private enum CodingKeys: String, CodingKey {
            case expiryEvents = "ExpiryEvents"
        }
    }

    public struct GetCertificateRequest: AWSEncodableShape {
        /// String that contains a certificate ARN in the following format:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String

        @inlinable
        public init(certificateArn: String) {
            self.certificateArn = certificateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct GetCertificateResponse: AWSDecodableShape {
        /// The ACM-issued certificate corresponding to the ARN specified as input.
        public let certificate: String?
        /// Certificates forming the requested certificate's chain of trust. The chain consists of the certificate of the issuing CA and the intermediate certificates of any other subordinate CAs.
        public let certificateChain: String?

        @inlinable
        public init(certificate: String? = nil, certificateChain: String? = nil) {
            self.certificate = certificate
            self.certificateChain = certificateChain
        }

        private enum CodingKeys: String, CodingKey {
            case certificate = "Certificate"
            case certificateChain = "CertificateChain"
        }
    }

    public struct HttpRedirect: AWSDecodableShape {
        /// The URL including the domain to be validated. The certificate authority sends GET requests here during validation.
        public let redirectFrom: String?
        /// The URL hosting the validation token. RedirectFrom must return this content or redirect here.
        public let redirectTo: String?

        @inlinable
        public init(redirectFrom: String? = nil, redirectTo: String? = nil) {
            self.redirectFrom = redirectFrom
            self.redirectTo = redirectTo
        }

        private enum CodingKeys: String, CodingKey {
            case redirectFrom = "RedirectFrom"
            case redirectTo = "RedirectTo"
        }
    }

    public struct ImportCertificateRequest: AWSEncodableShape {
        /// The certificate to import.
        public let certificate: AWSBase64Data
        /// The Amazon Resource Name (ARN) of an imported certificate to replace. To import a new certificate, omit this field.
        public let certificateArn: String?
        /// The PEM encoded certificate chain.
        public let certificateChain: AWSBase64Data?
        /// The private key that matches the public key in the certificate.
        public let privateKey: AWSBase64Data
        /// One or more resource tags to associate with the imported certificate.  Note: You cannot apply tags when reimporting a certificate.
        public let tags: [Tag]?

        @inlinable
        public init(certificate: AWSBase64Data, certificateArn: String? = nil, certificateChain: AWSBase64Data? = nil, privateKey: AWSBase64Data, tags: [Tag]? = nil) {
            self.certificate = certificate
            self.certificateArn = certificateArn
            self.certificateChain = certificateChain
            self.privateKey = privateKey
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.certificate, name: "certificate", parent: name, max: 32768)
            try self.validate(self.certificate, name: "certificate", parent: name, min: 1)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
            try self.validate(self.certificateChain, name: "certificateChain", parent: name, max: 2097152)
            try self.validate(self.certificateChain, name: "certificateChain", parent: name, min: 1)
            try self.validate(self.privateKey, name: "privateKey", parent: name, max: 5120)
            try self.validate(self.privateKey, name: "privateKey", parent: name, min: 1)
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case certificate = "Certificate"
            case certificateArn = "CertificateArn"
            case certificateChain = "CertificateChain"
            case privateKey = "PrivateKey"
            case tags = "Tags"
        }
    }

    public struct ImportCertificateResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the imported certificate.
        public let certificateArn: String?

        @inlinable
        public init(certificateArn: String? = nil) {
            self.certificateArn = certificateArn
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct KeyUsage: AWSDecodableShape {
        /// A string value that contains a Key Usage extension name.
        public let name: KeyUsageName?

        @inlinable
        public init(name: KeyUsageName? = nil) {
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
        }
    }

    public struct ListCertificatesRequest: AWSEncodableShape {
        /// Filter the certificate list by status value.
        public let certificateStatuses: [CertificateStatus]?
        /// Filter the certificate list. For more information, see the Filters structure.
        public let includes: Filters?
        /// Use this parameter when paginating results to specify the maximum number of items to return in the response. If additional items exist beyond the number you specify, the NextToken element is sent in the response. Use this NextToken value in a subsequent request to retrieve additional items.
        public let maxItems: Int?
        /// Use this parameter only when paginating results and only in a subsequent request after you receive a response with truncated results. Set it to the value of NextToken from the response you just received.
        public let nextToken: String?
        /// Specifies the field to sort results by. If you specify SortBy, you must also specify SortOrder.
        public let sortBy: SortBy?
        /// Specifies the order of sorted results. If you specify SortOrder, you must also specify SortBy.
        public let sortOrder: SortOrder?

        @inlinable
        public init(certificateStatuses: [CertificateStatus]? = nil, includes: Filters? = nil, maxItems: Int? = nil, nextToken: String? = nil, sortBy: SortBy? = nil, sortOrder: SortOrder? = nil) {
            self.certificateStatuses = certificateStatuses
            self.includes = includes
            self.maxItems = maxItems
            self.nextToken = nextToken
            self.sortBy = sortBy
            self.sortOrder = sortOrder
        }

        public func validate(name: String) throws {
            try self.validate(self.maxItems, name: "maxItems", parent: name, max: 1000)
            try self.validate(self.maxItems, name: "maxItems", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 10000)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\u0009\\u000A\\u000D\\u0020-\\u00FF]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateStatuses = "CertificateStatuses"
            case includes = "Includes"
            case maxItems = "MaxItems"
            case nextToken = "NextToken"
            case sortBy = "SortBy"
            case sortOrder = "SortOrder"
        }
    }

    public struct ListCertificatesResponse: AWSDecodableShape {
        /// A list of ACM certificates.
        public let certificateSummaryList: [CertificateSummary]?
        /// When the list is truncated, this value is present and contains the value to use for the NextToken parameter in a subsequent pagination request.
        public let nextToken: String?

        @inlinable
        public init(certificateSummaryList: [CertificateSummary]? = nil, nextToken: String? = nil) {
            self.certificateSummaryList = certificateSummaryList
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case certificateSummaryList = "CertificateSummaryList"
            case nextToken = "NextToken"
        }
    }

    public struct ListTagsForCertificateRequest: AWSEncodableShape {
        /// String that contains the ARN of the ACM certificate for which you want to list the tags. This must have the following form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String

        @inlinable
        public init(certificateArn: String) {
            self.certificateArn = certificateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct ListTagsForCertificateResponse: AWSDecodableShape {
        /// The key-value pairs that define the applied tags.
        public let tags: [Tag]?

        @inlinable
        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct PutAccountConfigurationRequest: AWSEncodableShape {
        /// Specifies expiration events associated with an account.
        public let expiryEvents: ExpiryEventsConfiguration?
        /// Customer-chosen string used to distinguish between calls to PutAccountConfiguration. Idempotency tokens time out after one hour. If you call PutAccountConfiguration multiple times with the same unexpired idempotency token, ACM treats it as the same request and returns the original result. If you change the idempotency token for each call, ACM treats each call as a new request.
        public let idempotencyToken: String

        @inlinable
        public init(expiryEvents: ExpiryEventsConfiguration? = nil, idempotencyToken: String) {
            self.expiryEvents = expiryEvents
            self.idempotencyToken = idempotencyToken
        }

        public func validate(name: String) throws {
            try self.expiryEvents?.validate(name: "\(name).expiryEvents")
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, max: 32)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, min: 1)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, pattern: "^\\w+$")
        }

        private enum CodingKeys: String, CodingKey {
            case expiryEvents = "ExpiryEvents"
            case idempotencyToken = "IdempotencyToken"
        }
    }

    public struct RemoveTagsFromCertificateRequest: AWSEncodableShape {
        /// String that contains the ARN of the ACM Certificate with one or more tags that you want to remove. This must be of the form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String
        /// The key-value pair that defines the tag to remove.
        public let tags: [Tag]

        @inlinable
        public init(certificateArn: String, tags: [Tag]) {
            self.certificateArn = certificateArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case tags = "Tags"
        }
    }

    public struct RenewCertificateRequest: AWSEncodableShape {
        /// String that contains the ARN of the ACM certificate to be renewed. This must be of the form:  arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012  For more information about ARNs, see Amazon Resource Names (ARNs).
        public let certificateArn: String

        @inlinable
        public init(certificateArn: String) {
            self.certificateArn = certificateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct RenewalSummary: AWSDecodableShape {
        /// Contains information about the validation of each domain name in the certificate, as it pertains to ACM's managed renewal. This is different from the initial validation that occurs as a result of the RequestCertificate request. This field exists only when the certificate type is AMAZON_ISSUED.
        public let domainValidationOptions: [DomainValidation]
        /// The status of ACM's managed renewal of the certificate.
        public let renewalStatus: RenewalStatus
        /// The reason that a renewal request was unsuccessful.
        public let renewalStatusReason: FailureReason?
        /// The time at which the renewal summary was last updated.
        public let updatedAt: Date

        @inlinable
        public init(domainValidationOptions: [DomainValidation], renewalStatus: RenewalStatus, renewalStatusReason: FailureReason? = nil, updatedAt: Date) {
            self.domainValidationOptions = domainValidationOptions
            self.renewalStatus = renewalStatus
            self.renewalStatusReason = renewalStatusReason
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case domainValidationOptions = "DomainValidationOptions"
            case renewalStatus = "RenewalStatus"
            case renewalStatusReason = "RenewalStatusReason"
            case updatedAt = "UpdatedAt"
        }
    }

    public struct RequestCertificateRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the private certificate authority (CA) that will be used to issue the certificate. If you do not provide an ARN and you are trying to request a private certificate, ACM will attempt to issue a public certificate. For more information about private CAs, see the Amazon Web Services Private Certificate Authority user guide. The ARN must have the following form:   arn:aws:acm-pca:region:account:certificate-authority/12345678-1234-1234-1234-123456789012
        public let certificateAuthorityArn: String?
        /// Fully qualified domain name (FQDN), such as www.example.com, that you want to secure with an ACM certificate. Use an asterisk (*) to create a wildcard certificate that protects several sites in the same domain. For example, *.example.com protects www.example.com, site.example.com, and images.example.com.  In compliance with RFC 5280, the length of the domain name (technically, the Common Name) that you provide cannot exceed 64 octets (characters), including periods. To add a longer domain name, specify it in the Subject Alternative Name field, which supports names up to 253 octets in length.
        public let domainName: String
        /// The domain name that you want ACM to use to send you emails so that you can validate domain ownership.
        public let domainValidationOptions: [DomainValidationOption]?
        /// Customer chosen string that can be used to distinguish between calls to RequestCertificate. Idempotency tokens time out after one hour. Therefore, if you call RequestCertificate multiple times with the same idempotency token within one hour, ACM recognizes that you are requesting only one certificate and will issue only one. If you change the idempotency token for each call, ACM recognizes that you are requesting multiple certificates.
        public let idempotencyToken: String?
        /// Specifies the algorithm of the public and private key pair that your certificate uses to encrypt data. RSA is the default key algorithm for ACM certificates. Elliptic Curve Digital Signature Algorithm (ECDSA) keys are smaller, offering security comparable to RSA keys but with greater computing efficiency. However, ECDSA is not supported by all network clients. Some Amazon Web Services services may require RSA keys, or only support ECDSA keys of a particular size, while others allow the use of either RSA and ECDSA keys to ensure that compatibility is not broken. Check the requirements for the Amazon Web Services service where you plan to deploy your certificate. For more information about selecting an algorithm, see Key algorithms.  Algorithms supported for an ACM certificate request include:     RSA_2048     EC_prime256v1     EC_secp384r1    Other listed algorithms are for imported certificates only.    When you request a private PKI certificate signed by a CA from Amazon Web Services Private CA, the specified signing algorithm family (RSA or ECDSA) must match the algorithm family of the CA's secret key.  Default: RSA_2048
        public let keyAlgorithm: KeyAlgorithm?
        /// Identifies the Amazon Web Services service that manages the certificate issued by ACM.
        public let managedBy: CertificateManagedBy?
        /// You can use this parameter to specify whether to add the certificate to a certificate transparency log and export your certificate. Certificate transparency makes it possible to detect SSL/TLS certificates that have been mistakenly or maliciously issued. Certificates that have not been logged typically produce an error message in a browser. For more information, see Opting Out of Certificate Transparency Logging. You can export public ACM certificates to use with Amazon Web Services services as well as outside the Amazon Web Services Cloud. For more information, see Certificate Manager exportable public certificate.
        public let options: CertificateOptions?
        /// Additional FQDNs to be included in the Subject Alternative Name extension of the ACM certificate. For example, add the name www.example.net to a certificate for which the DomainName field is www.example.com if users can reach your site by using either name. The maximum number of domain names that you can add to an ACM certificate is 100. However, the initial quota is 10 domain names. If you need more than 10 names, you must request a quota increase. For more information, see Quotas.  The maximum length of a SAN DNS name is 253 octets. The name is made up of multiple labels separated by periods. No label can be longer than 63 octets. Consider the following examples:     (63 octets).(63 octets).(63 octets).(61 octets) is legal because the total length is 253 octets (63+1+63+1+63+1+61) and no label exceeds 63 octets.    (64 octets).(63 octets).(63 octets).(61 octets) is not legal because the total length exceeds 253 octets (64+1+63+1+63+1+61) and the first label exceeds 63 octets.    (63 octets).(63 octets).(63 octets).(62 octets) is not legal because the total length of the DNS name (63+1+63+1+63+1+62) exceeds 253 octets.
        public let subjectAlternativeNames: [String]?
        /// One or more resource tags to associate with the certificate.
        public let tags: [Tag]?
        /// The method you want to use if you are requesting a public certificate to validate that you own or control domain. You can validate with DNS or validate with email. We recommend that you use DNS validation.
        public let validationMethod: ValidationMethod?

        @inlinable
        public init(certificateAuthorityArn: String? = nil, domainName: String, domainValidationOptions: [DomainValidationOption]? = nil, idempotencyToken: String? = nil, keyAlgorithm: KeyAlgorithm? = nil, managedBy: CertificateManagedBy? = nil, options: CertificateOptions? = nil, subjectAlternativeNames: [String]? = nil, tags: [Tag]? = nil, validationMethod: ValidationMethod? = nil) {
            self.certificateAuthorityArn = certificateAuthorityArn
            self.domainName = domainName
            self.domainValidationOptions = domainValidationOptions
            self.idempotencyToken = idempotencyToken
            self.keyAlgorithm = keyAlgorithm
            self.managedBy = managedBy
            self.options = options
            self.subjectAlternativeNames = subjectAlternativeNames
            self.tags = tags
            self.validationMethod = validationMethod
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateAuthorityArn, name: "certificateAuthorityArn", parent: name, max: 2048)
            try self.validate(self.certificateAuthorityArn, name: "certificateAuthorityArn", parent: name, min: 20)
            try self.validate(self.certificateAuthorityArn, name: "certificateAuthorityArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm-pca:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
            try self.validate(self.domainName, name: "domainName", parent: name, max: 253)
            try self.validate(self.domainName, name: "domainName", parent: name, min: 1)
            try self.validate(self.domainName, name: "domainName", parent: name, pattern: "^(\\*\\.)?(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
            try self.domainValidationOptions?.forEach {
                try $0.validate(name: "\(name).domainValidationOptions[]")
            }
            try self.validate(self.domainValidationOptions, name: "domainValidationOptions", parent: name, max: 100)
            try self.validate(self.domainValidationOptions, name: "domainValidationOptions", parent: name, min: 1)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, max: 32)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, min: 1)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, pattern: "^\\w+$")
            try self.subjectAlternativeNames?.forEach {
                try validate($0, name: "subjectAlternativeNames[]", parent: name, max: 253)
                try validate($0, name: "subjectAlternativeNames[]", parent: name, min: 1)
                try validate($0, name: "subjectAlternativeNames[]", parent: name, pattern: "^(\\*\\.)?(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
            }
            try self.validate(self.subjectAlternativeNames, name: "subjectAlternativeNames", parent: name, max: 100)
            try self.validate(self.subjectAlternativeNames, name: "subjectAlternativeNames", parent: name, min: 1)
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case certificateAuthorityArn = "CertificateAuthorityArn"
            case domainName = "DomainName"
            case domainValidationOptions = "DomainValidationOptions"
            case idempotencyToken = "IdempotencyToken"
            case keyAlgorithm = "KeyAlgorithm"
            case managedBy = "ManagedBy"
            case options = "Options"
            case subjectAlternativeNames = "SubjectAlternativeNames"
            case tags = "Tags"
            case validationMethod = "ValidationMethod"
        }
    }

    public struct RequestCertificateResponse: AWSDecodableShape {
        /// String that contains the ARN of the issued certificate. This must be of the form:  arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
        public let certificateArn: String?

        @inlinable
        public init(certificateArn: String? = nil) {
            self.certificateArn = certificateArn
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct ResendValidationEmailRequest: AWSEncodableShape {
        /// String that contains the ARN of the requested certificate. The certificate ARN is generated and returned by the RequestCertificate action as soon as the request is made. By default, using this parameter causes email to be sent to all top-level domains you specified in the certificate request. The ARN must be of the form:   arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
        public let certificateArn: String
        /// The fully qualified domain name (FQDN) of the certificate that needs to be validated.
        public let domain: String
        /// The base validation domain that will act as the suffix of the email addresses that are used to send the emails. This must be the same as the Domain value or a superdomain of the Domain value. For example, if you requested a certificate for site.subdomain.example.com and specify a ValidationDomain of subdomain.example.com, ACM sends email to the domain registrant, technical contact, and administrative contact in WHOIS and the following five addresses:   admin@subdomain.example.com   administrator@subdomain.example.com   hostmaster@subdomain.example.com   postmaster@subdomain.example.com   webmaster@subdomain.example.com
        public let validationDomain: String

        @inlinable
        public init(certificateArn: String, domain: String, validationDomain: String) {
            self.certificateArn = certificateArn
            self.domain = domain
            self.validationDomain = validationDomain
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
            try self.validate(self.domain, name: "domain", parent: name, max: 253)
            try self.validate(self.domain, name: "domain", parent: name, min: 1)
            try self.validate(self.domain, name: "domain", parent: name, pattern: "^(\\*\\.)?(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
            try self.validate(self.validationDomain, name: "validationDomain", parent: name, max: 253)
            try self.validate(self.validationDomain, name: "validationDomain", parent: name, min: 1)
            try self.validate(self.validationDomain, name: "validationDomain", parent: name, pattern: "^(\\*\\.)?(((?!-)[A-Za-z0-9-]{0,62}[A-Za-z0-9])\\.)+((?!-)[A-Za-z0-9-]{1,62}[A-Za-z0-9])$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case domain = "Domain"
            case validationDomain = "ValidationDomain"
        }
    }

    public struct ResourceRecord: AWSDecodableShape {
        /// The name of the DNS record to create in your domain. This is supplied by ACM.
        public let name: String
        /// The type of DNS record. Currently this can be CNAME.
        public let type: RecordType
        /// The value of the CNAME record to add to your DNS database. This is supplied by ACM.
        public let value: String

        @inlinable
        public init(name: String, type: RecordType, value: String) {
            self.name = name
            self.type = type
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case type = "Type"
            case value = "Value"
        }
    }

    public struct RevokeCertificateRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the public or private certificate that will be revoked. The ARN must have the following form:   arn:aws:acm:region:account:certificate/12345678-1234-1234-1234-123456789012
        public let certificateArn: String
        /// Specifies why you revoked the certificate.
        public let revocationReason: RevocationReason

        @inlinable
        public init(certificateArn: String, revocationReason: RevocationReason) {
            self.certificateArn = certificateArn
            self.revocationReason = revocationReason
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case revocationReason = "RevocationReason"
        }
    }

    public struct RevokeCertificateResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the public or private certificate that was revoked.
        public let certificateArn: String?

        @inlinable
        public init(certificateArn: String? = nil) {
            self.certificateArn = certificateArn
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The key of the tag.
        public let key: String
        /// The value of the tag.
        public let value: String?

        @inlinable
        public init(key: String, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.:\\/=+\\-@]*$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.:\\/=+\\-@]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct UpdateCertificateOptionsRequest: AWSEncodableShape {
        /// ARN of the requested certificate to update. This must be of the form:  arn:aws:acm:us-east-1:account:certificate/12345678-1234-1234-1234-123456789012
        public let certificateArn: String
        /// Use to update the options for your certificate. Currently, you can specify whether to add your certificate to a transparency log or export your certificate. Certificate transparency makes it possible to detect SSL/TLS certificates that have been mistakenly or maliciously issued. Certificates that have not been logged typically produce an error message in a browser.
        public let options: CertificateOptions

        @inlinable
        public init(certificateArn: String, options: CertificateOptions) {
            self.certificateArn = certificateArn
            self.options = options
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:[\\w+=/,.@-]+:acm:[\\w+=/,.@-]*:[0-9]+:[\\w+=,.@-]+(/[\\w+=,.@-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case options = "Options"
        }
    }
}

// MARK: - Errors

/// Error enum for ACM
public struct ACMErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case invalidArgsException = "InvalidArgsException"
        case invalidArnException = "InvalidArnException"
        case invalidDomainValidationOptionsException = "InvalidDomainValidationOptionsException"
        case invalidParameterException = "InvalidParameterException"
        case invalidStateException = "InvalidStateException"
        case invalidTagException = "InvalidTagException"
        case limitExceededException = "LimitExceededException"
        case requestInProgressException = "RequestInProgressException"
        case resourceInUseException = "ResourceInUseException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case tagPolicyException = "TagPolicyException"
        case throttlingException = "ThrottlingException"
        case tooManyTagsException = "TooManyTagsException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize ACM
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have access required to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// You are trying to update a resource or configuration that is already being created or updated. Wait for the previous operation to finish and try again.
    public static var conflictException: Self { .init(.conflictException) }
    /// One or more of request parameters specified is not valid.
    public static var invalidArgsException: Self { .init(.invalidArgsException) }
    /// The requested Amazon Resource Name (ARN) does not refer to an existing resource.
    public static var invalidArnException: Self { .init(.invalidArnException) }
    /// One or more values in the DomainValidationOption structure is incorrect.
    public static var invalidDomainValidationOptionsException: Self { .init(.invalidDomainValidationOptionsException) }
    /// An input parameter was invalid.
    public static var invalidParameterException: Self { .init(.invalidParameterException) }
    /// Processing has reached an invalid state.
    public static var invalidStateException: Self { .init(.invalidStateException) }
    /// One or both of the values that make up the key-value pair is not valid. For example, you cannot specify a tag value that begins with aws:.
    public static var invalidTagException: Self { .init(.invalidTagException) }
    /// An ACM quota has been exceeded.
    public static var limitExceededException: Self { .init(.limitExceededException) }
    /// The certificate request is in process and the certificate in your account has not yet been issued.
    public static var requestInProgressException: Self { .init(.requestInProgressException) }
    /// The certificate is in use by another Amazon Web Services service in the caller's account. Remove the association and try again.
    public static var resourceInUseException: Self { .init(.resourceInUseException) }
    /// The specified certificate cannot be found in the caller's account or the caller's account cannot be found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// A specified tag did not comply with an existing tag policy and was rejected.
    public static var tagPolicyException: Self { .init(.tagPolicyException) }
    /// The request was denied because it exceeded a quota.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The request contains too many tags. Try the request again with fewer tags.
    public static var tooManyTagsException: Self { .init(.tooManyTagsException) }
    /// The supplied input failed to satisfy constraints of an Amazon Web Services service.
    public static var validationException: Self { .init(.validationException) }
}

extension ACMErrorType: Equatable {
    public static func == (lhs: ACMErrorType, rhs: ACMErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension ACMErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
